<?php
/**
* Verification code class. <br />
* 
* @author liuxiao<seanliu707@gmial.com>
* @copyright Swolf 2015
* @version 1.0
*/
class Captcha {
	private $codes = NULL;
	private $img = NULL;
	private $img_width = 70;
	private $img_height = 30;
	private $font_size = 12;
	
	private static $instance = NULL;
	private static $string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
	
	public static function getInstance() {
		if ( self::$instance == NULL )
			self::$instance = new self();
		return self::$instance;
	}
	
	public function __construct() {}
	
	/*
	functions of setting image width/height and font size.
	*/
	public function setImgWidth($width) {
		$this->img_width = $width;
		return $this;
	}
	public function setImgHeight($height) {
		$this->img_height = $height;
		return $this;
	}
	public function setFontSize($size) {
		$this->font_size = $size;
		return $this;
	}
	
	/**
	 * create an random string of specified length
	 * @param int $len
	 * @return string
	 */
	/* public function randomText( $len = 5 ) {
		$length = strlen(self::$string);
		$this->codes = '';
		$idx = 0;
		for ( $i = 0 ; $i < $len ; $i++ ) {
			$idx = mt_rand() % $length;
			$this->codes .= self::$string[$idx];
		}
		//return $this->codes;
	} */
	
	/**
	 * create and show an image with specified string 
	 * @param string $format
	 */
	public function showImg( $len = 5, $format = 'gif' ) {
		//create an new image
		if ( $this->img == NULL )
			$this->img = imagecreatetruecolor( $this->img_width, $this->img_height );
		
		//fill background color
		$bg_color = imagecolorallocate( $this->img , mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255) );
		imagefilledrectangle( $this->img, 0, 0, $this->img_width, $this->img_height, $bg_color );
		
		//add some lines
		for ( $n = 0; $n < $len; $n++ ){
			$x1 = mt_rand(0,$this->img_width);
			$y1 = mt_rand(0,$this->img_height);
			$x2 = mt_rand(0,$this->img_width);
			$y2 = mt_rand(0,$this->img_height);
			$_line_color = imagecolorallocate( $this->img , mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200) );
			imageline($this->img,$x1,$y1,$x2,$y2,$_line_color);
		}
		
		// create an random string of specified length
		$strlength = strlen(self::$string);
		$this->codes = '';
		$idx = 0;
		for ( $i = 0 ; $i < $len ; $i++ ) {
			$idx = mt_rand() % $strlength;
			$this->codes .= self::$string[$idx];
		} 
		
		//draw specified string to the image
		$font_color = imagecolorallocate( $this->img, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100) );
		$angle = 0;
		$length = strlen( $this->codes );
		$font = dirname(__FILE__).DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.'ariblk.ttf';
		
		for ( $i = 0 ; $i < $length ; $i++ ) {
			//set font`s angle less than 30
			$angle = mt_rand() % 30;
			//set x , y
			$paddingX = 10;
			$offset = ($this->img_width - $paddingX*2)/$length;
			$y = $this->img_height/2 + mt_rand()%($this->img_height/5);
			//(mt_rand() & 1) == 0  mt_rand is even number
			imagettftext( $this->img, $this->font_size, (mt_rand() & 1) == 0 ? $angle : -$angle , $paddingX+$offset*$i, $y, $font_color, $font, $this->codes[$i]);
		}
		
		//add some pixels
		for($j = 0; $j < $len * 20; $j++){
			$a = mt_rand(0,$this->img_width);
			$b = mt_rand(0,$this->img_height);
			ImageSetPixel($this->img,$a,$b,$font_color); //添加干扰像素
		}
		
		//show the image
		$format = strtolower($format);
		if ( $format == 'gif' ) {
			header('Content-Type:image/gif');
			imagegif($this->img);
		} else if ( $format == 'jpg' || $format == 'jpeg' ) {
			header('Content-Type:image/jpeg');
			imagejpeg($this->img);
		} else if ( $format == 'png' ) {
			header('Content-Type:image/png');
			imagepng($this->img);
		} else if ( $format == 'wbmp' ) {
			header('Content-Type:image/vnd.wap.wbmp');
			imagewbmp($this->img);
		} else echo '不支持'.$format.'格式图像创建！';
	}
	//get the random string
	public function getString(){
		return  $this->codes;
	}
	public function __destruct() {
		imagedestroy($this->img);
	}
}